home *** CD-ROM | disk | FTP | other *** search
- /*
- ** ARexx.c
- **
- ** ARexx interface general support routines
- **
- ** Copyright © 1990-1996 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- */
-
- #ifndef _GLOBAL_H
- #include "Global.h"
- #endif
-
- /* IsNumeric(STRPTR String):
- *
- * Is the string really a number?
- */
-
- BOOL
- IsNumeric(STRPTR String)
- {
- while(*String && (*String == ' ' || *String == '\t'))
- String++;
-
- while(*String)
- {
- if(*String < '0' || *String > '9')
- return(FALSE);
- else
- String++;
- }
-
- return(TRUE);
- }
-
- /* CreateResult(STRPTR ResultString,LONG *Results):
- *
- * Create a proper Rexx result string.
- */
-
- STRPTR
- CreateResult(STRPTR ResultString,LONG *Results)
- {
- STRPTR Result;
-
- if(!(Result = CreateArgstring(ResultString,strlen(ResultString))))
- {
- Results[0] = RC_ERROR;
- Results[1] = ERROR_NO_FREE_STORE;
- }
-
- return(Result);
- }
-
- /* CreateResultLen(STRPTR ResultString,LONG *Results):
- *
- * Create a proper Rexx result string given the
- * length of the source string.
- */
-
- STRPTR
- CreateResultLen(STRPTR ResultString,LONG *Results,LONG Len)
- {
- STRPTR Result;
-
- if(!(Result = CreateArgstring(ResultString,Len)))
- {
- Results[0] = RC_ERROR;
- Results[1] = ERROR_NO_FREE_STORE;
- }
-
- return(Result);
- }
-
- /* CreateVarArgs(STRPTR Value,struct RexxPkt *Packet,STRPTR Stem,...):
- *
- * Set a Rexx variable, special treatment.
- */
-
- BOOL __stdargs
- CreateVarArgs(STRPTR Value,struct RexxPkt *Packet,STRPTR Stem,...)
- {
- UBYTE Name[256];
- va_list VarArgs;
- LONG Result;
-
- va_start(VarArgs,Stem);
- VSPrintf(Name,Stem,VarArgs);
- va_end(VarArgs);
-
- if(Result = SetRexxVar(Packet -> RexxMsg,Name,Value,strlen(Value)))
- {
- Packet -> Results[0] = RC_ERROR;
- Packet -> Results[1] = Result;
-
- return(FALSE);
- }
- else
- return(TRUE);
- }
-
- /* CreateVar(STRPTR Value,struct RexxPkt *Packet,STRPTR Name):
- *
- * Set a Rexx variable, simple version.
- */
-
- STRPTR
- CreateVar(STRPTR Value,struct RexxPkt *Packet,STRPTR Name)
- {
- LONG Result;
-
- if(Result = SetRexxVar(Packet -> RexxMsg,Name,Value,strlen(Value)))
- {
- Packet -> Results[0] = RC_ERROR;
- Packet -> Results[1] = Result;
- }
-
- return(NULL);
- }
-
- /* CreateMatchBuffer(STRPTR Pattern):
- *
- * Create a pattern buffer suitable for pattern matching.
- */
-
- STRPTR
- CreateMatchBuffer(STRPTR Pattern)
- {
- LONG Len = strlen(Pattern) + 1;
- STRPTR Buffer;
-
- if(Buffer = (STRPTR)AllocVecPooled(2 * Len,MEMF_ANY))
- {
- if(ParsePatternNoCase(Pattern,Buffer,2 * Len) != -1)
- return(Buffer);
- else
- FreeVecPooled(Buffer);
- }
-
- return(NULL);
- }
-
- /* MatchBuffer(STRPTR Buffer,STRPTR Name):
- *
- * Match a pattern against a string.
- */
-
- BOOL
- MatchBuffer(STRPTR Buffer,STRPTR Name)
- {
- return((BOOL)(MatchPatternNoCase(Buffer,Name) != FALSE));
- }
-
- /* DeleteMatchBuffer(STRPTR Buffer):
- *
- * Free a pattern matching buffer.
- */
-
- VOID
- DeleteMatchBuffer(STRPTR Buffer)
- {
- FreeVecPooled(Buffer);
- }
-
- /* ToMode(STRPTR Name):
- *
- * Turn a transfer mode name into a key.
- */
-
- LONG
- ToMode(STRPTR Name)
- {
- STATIC STRPTR TransferModes[] =
- {
- "BINARY",
- "TEXT",
- "ASCII",
- NULL
- };
-
- LONG i;
-
- for(i = 0 ; TransferModes[i] ; i++)
- {
- if(!Stricmp(Name,TransferModes[i]))
- return(i);
- }
-
- return(-1);
- }
-
- /* ToList(STRPTR Name):
- *
- * Turn a list name into a key.
- */
-
- LONG
- ToList(STRPTR Name)
- {
- STATIC STRPTR ListTypes[GLIST_COUNT] =
- {
- "UPLOAD",
- "DOWNLOAD",
- "DIAL",
- "WAIT",
- "TRAP"
- };
-
- LONG i;
-
- for(i = 0 ; i < GLIST_COUNT ; i++)
- {
- if(!Stricmp(Name,ListTypes[i]))
- return(i);
- }
-
- return(-1);
- }
-
- /* ToConfig(STRPTR Name):
- *
- * Turn a configuration name into a key.
- */
-
- LONG
- ToConfig(STRPTR Name)
- {
- STATIC STRPTR DataTypes[DATATYPE_COUNT] =
- {
- "TRANSLATIONS",
- "FUNCTIONKEYS",
- "CURSORKEYS",
- "FASTMACROS",
- "HOTKEYS",
- "SPEECH",
- "SOUND",
- "BUFFER",
- "CONFIGURATION",
- "PHONE",
- "SCREENTEXT",
- "SCREENIMAGE"
- };
-
- LONG i;
-
- for(i = 0 ; i < DATATYPE_COUNT ; i++)
- {
- if(!Stricmp(Name,DataTypes[i]))
- return(i);
- }
-
- return(-1);
- }
-
- /* ToRequester(STRPTR Name):
- *
- * Turn a requester name into a key.
- */
-
- LONG
- ToRequester(STRPTR Name)
- {
- STRPTR RequesterTypes[REQUESTER_COUNT] =
- {
- "SERIAL",
- "MODEM",
- "SCREEN",
- "TERMINAL",
- "EMULATION",
- "CLIPBOARD",
- "CAPTURE",
- "COMMANDS",
- "MISC",
- "PATH",
- "TRANSFER",
- "TRANSLATIONS",
- "FUNCTIONKEYS",
- "CURSORKEYS",
- "FASTMACROS",
- "HOTKEYS",
- "SPEECH",
- "SOUND",
- "PHONE"
- };
-
- LONG i;
-
- for(i = 0 ; i < REQUESTER_COUNT ; i++)
- {
- if(!Stricmp(Name,RequesterTypes[i]))
- return(i);
- }
-
- return(-1);
- }
-
- /* ToWindow(STRPTR Name):
- *
- * Turn a window name into a key.
- */
-
- LONG
- ToWindow(STRPTR Name)
- {
- STATIC STRPTR WindowTypes[WINDOWID_COUNT] =
- {
- "BUFFER",
- "REVIEW",
- "PACKET",
- "FASTMACROS",
- "STATUS",
- "MAIN",
- "UPLOADQUEUE",
- "SINGLECHARENTRY"
- };
-
- LONG i;
-
- for(i = 0 ; i < WINDOWID_COUNT ; i++)
- {
- if(!Stricmp(WindowTypes[i],Name))
- return(i);
- }
-
- return(-1);
- }
-
- /* ReplyRexxCommand():
- *
- * Reply a command request the rexx server - or someone else -
- * has passed to us.
- */
-
- STATIC VOID
- ReplyRexxCommand(struct RexxMsg *RexxMessage,LONG Primary,LONG Secondary)
- {
- if(RexxMessage)
- {
- RexxMessage -> rm_Result1 = Primary;
- RexxMessage -> rm_Result2 = Secondary;
-
- ReplyMsg(RexxMessage);
- }
- }
-
- /* RexxToolServer(VOID):
- *
- * Asynchronous tool/rexx command execution process.
- */
-
- STATIC VOID __saveds
- RexxToolServer(VOID)
- {
- struct Process *ThisProcess = (struct Process *)FindTask(NULL);
- struct RexxPkt *Packet;
- BPTR NewCOS = NULL;
-
- /* Wait for startup packet. */
-
- WaitPort(&ThisProcess -> pr_MsgPort);
-
- Packet = (struct RexxPkt *)GetMsg(&ThisProcess -> pr_MsgPort);
-
- /* Increment usage count. */
-
- ObtainSemaphore(&RexxLaunchSemaphore);
-
- RexxLaunchCount++;
-
- ReleaseSemaphore(&RexxLaunchSemaphore);
-
- /* Create proper output stream if necessary. */
-
- if(!Output() && GetConsoleTask())
- {
- if(NewCOS = Open("CONSOLE:",MODE_NEWFILE))
- SelectOutput(NewCOS);
- }
-
- /* Execute the command. */
-
- (*Packet -> CommandInfo -> Routine)(Packet);
-
- Forbid();
-
- /* Decrement usage count. */
-
- ObtainSemaphore(&RexxLaunchSemaphore);
-
- RexxLaunchCount--;
-
- ReleaseSemaphore(&RexxLaunchSemaphore);
-
- /* Close the output stream. */
-
- if(NewCOS)
- {
- SelectOutput(NULL);
-
- Close(NewCOS);
- }
-
- /* Return the message packet. */
-
- ReplyMsg((struct Message *)Packet);
- }
-
- /* InvokeRexxCommand(struct RexxPkt *Packet):
- *
- * Invoke an ARexx command.
- */
-
- STATIC BOOL
- InvokeRexxCommand(struct RexxPkt *Packet)
- {
- /* Asynchronous command? */
-
- if(Packet -> CommandInfo -> Async)
- {
- /* Requires special execution code? */
-
- if(Packet -> CommandInfo -> Tool)
- {
- struct RexxPkt *NewPacket;
-
- /* Create a command packet. */
-
- if(NewPacket = (struct RexxPkt *)AllocVecPooled(sizeof(struct RexxPkt),MEMF_ANY | MEMF_PUBLIC))
- {
- enum { ARG_CONSOLE };
-
- struct Process *NewProcess;
- BPTR Stream;
-
- /* Set up the command packet. */
-
- CopyMem(Packet,NewPacket,sizeof(struct RexxPkt));
-
- NewPacket -> VanillaMessage . mn_ReplyPort = RexxPort;
- NewPacket -> VanillaMessage . mn_Length = sizeof(struct RexxPkt);
-
- /* Create I/O streams. */
-
- if(Packet -> Array[ARG_CONSOLE] && WindowName[0] && Packet -> CommandInfo -> Console)
- Stream = Open(WindowName,MODE_NEWFILE);
- else
- Stream = NULL;
-
- /* Launch the process. */
-
- if(NewProcess = LaunchProcess("term Rexx Tool Process",RexxToolServer,Stream))
- PutMsg(&NewProcess -> pr_MsgPort,(struct Message *)NewPacket);
- else
- {
- FreeVecPooled(NewPacket);
-
- ReplyRexxCommand(Packet -> RexxMsg,-1,0);
-
- if(Stream)
- Close(Stream);
- }
- }
- else
- ReplyRexxCommand(Packet -> RexxMsg,-1,0);
- }
- else
- {
- /* Execute the command on the schedule of the
- * rexx server process.
- */
-
- STRPTR Result = (*Packet -> CommandInfo -> Routine)(Packet);
-
- RexxPktCleanup(Packet,Result);
- }
- }
- else
- {
- struct RexxPkt *NewPacket;
-
- /* Create message packet. */
-
- if(NewPacket = (struct RexxPkt *)AllocVecPooled(sizeof(struct RexxPkt),MEMF_ANY | MEMF_PUBLIC))
- {
- /* Set up message packet. */
-
- CopyMem(Packet,NewPacket,sizeof(struct RexxPkt));
-
- NewPacket -> VanillaMessage . mn_ReplyPort = RexxPort;
- NewPacket -> VanillaMessage . mn_Length = sizeof(struct RexxPkt);
-
- /* Post it. */
-
- PutMsg(TermRexxPort,(struct Message *)NewPacket);
- }
- else
- ReplyRexxCommand(Packet -> RexxMsg,-1,0);
- }
-
- return(TRUE);
- }
-
- /* ParseRexxCommand(struct RexxMsg *RexxMsg):
- *
- * Handles the synchronous Rexx commands and returns the
- * message if no matching command is found.
- */
-
- STATIC BOOL
- ParseRexxCommand(struct RexxMsg *RexxMsg)
- {
- UBYTE CommandBuffer[30];
- STRPTR Command,
- CommandArgs;
- LONG Len = 0;
-
- /* Clear the local variables. */
-
- CommandBuffer[0] = 0;
- Command = RexxMsg -> rm_Args[0];
- CommandArgs = NULL;
-
- /* Skip leading blank spaces. */
-
- while(*Command && (*Command == ' ' || *Command == '\t'))
- Command++;
-
- /* Extract the command name. */
-
- do
- {
- /* Found the end of the string? */
-
- if(!Command[Len])
- {
- /* Copy the command name. */
-
- strcpy(CommandBuffer,Command);
-
- /* No arguments are provided. */
-
- CommandArgs = NULL;
-
- break;
- }
-
- /* Found a blank space? */
-
- if(Command[Len] == ' ' || Command[Len] == '\t')
- {
- /* Copy the command name. */
-
- CopyMem(Command,CommandBuffer,Len);
-
- CommandBuffer[Len] = 0;
-
- /* Look for any arguments. */
-
- CommandArgs = &Command[Len + 1];
-
- /* Skip blank spaces. */
-
- while(*CommandArgs && (*CommandArgs == ' ' || *CommandArgs == '\t'))
- CommandArgs++;
-
- break;
- }
- }
- while(++Len < 30);
-
- /* Did we find a command name? */
-
- if(CommandBuffer[0])
- {
- struct CommandInfo *CommandInfo = NULL;
- LONG CommandIndex;
-
- /* Which command is it? */
-
- for(CommandIndex = 0 ; CommandIndex < CommandTableSize ; CommandIndex++)
- {
- if(!Stricmp(CommandBuffer,CommandTable[CommandIndex] . Name))
- {
- CommandInfo = &CommandTable[CommandIndex];
-
- break;
- }
- }
-
- /* Did we find the command? */
-
- if(CommandInfo)
- {
- struct RexxPkt __aligned Packet;
- BOOL Processed = FALSE;
-
- /* Set the result codes to defaults. */
-
- Packet . Results[0] = RC_OK;
- Packet . Results[1] = 0;
-
- /* Fill in the rest. */
-
- Packet . CommandInfo = CommandInfo;
- Packet . RexxMsg = RexxMsg;
-
- /* Does this command accept any arguments? */
-
- if(CommandInfo -> Arguments)
- {
- LONG *Array;
-
- /* Determine length of argument string. */
-
- if(CommandArgs)
- Len = strlen(CommandArgs);
- else
- Len = 0;
-
- /* Allocate temporary buffer, we will need to
- * attach a line-feed character to the argument
- * string.
- */
-
- if(Array = (LONG *)AllocVecPooled(12 * sizeof(LONG) + Len + 2,MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC))
- {
- STRPTR Buffer;
- struct RDArgs *Args;
-
- /* Get the argument buffer. */
-
- Buffer = (STRPTR)&Array[12];
-
- /* Copy the argument string. */
-
- if(CommandArgs && Len)
- CopyMem(CommandArgs,Buffer,Len);
-
- /* Attach the line-feed character. */
-
- Buffer[Len] = '\n';
-
- /* Allocate argument parser data. */
-
- if(Args = (struct RDArgs *)AllocDosObjectTags(DOS_RDARGS,TAG_DONE))
- {
- Packet . Array = (STRPTR *)Array;
- Packet . Args = Args;
-
- /* Don't prompt for input! */
-
- Args -> RDA_Flags |= RDAF_NOPROMPT;
-
- /* Set up parser data. */
-
- Args -> RDA_Source . CS_Buffer = Buffer;
- Args -> RDA_Source . CS_Length = Len + 1;
- Args -> RDA_Source . CS_CurChr = 0;
-
- /* Parse the arguments. */
-
- if(ReadArgs(CommandInfo -> Arguments,Array,Args))
- {
- UWORD Inclusion = InclusionTable[CommandIndex];
- BOOL ArgsRequired = FALSE;
- LONG i,Counted;
-
- /* Look for required arguments. */
-
- for(i = Counted = 0 ; i < 12 ; i++)
- {
- if(Inclusion & (1L << i))
- {
- ArgsRequired = TRUE;
-
- if(Array[i])
- Counted++;
- }
- }
-
- /* Are any arguments required
- * but not provided?
- */
-
- if(ArgsRequired && !Counted)
- {
- Packet . Results[0] = RC_ERROR;
- Packet . Results[1] = ERROR_REQUIRED_ARG_MISSING;
- }
- else
- {
- struct ExclusionInfo *Exclusion = ExclusionTable[CommandIndex];
-
- /* Any mutually-exclusive arguments? */
-
- if(Exclusion)
- {
- BOOL ArgsOkay = TRUE;
-
- i = 0;
-
- /* Look for arguments to
- * exclude each other.
- */
-
- while(ArgsOkay && Exclusion[i] . A != -1)
- {
- if(Array[Exclusion[i] . A] && Array[Exclusion[i] . B])
- ArgsOkay = FALSE;
- else
- i++;
- }
-
- /* All arguments correct? */
-
- if(ArgsOkay)
- Processed = InvokeRexxCommand(&Packet);
- else
- {
- Packet . Results[0] = RC_ERROR;
- Packet . Results[1] = ERROR_TOO_MANY_ARGS;
- }
- }
- else
- Processed = InvokeRexxCommand(&Packet);
- }
-
- /* Free allocated parser data. */
-
- if(!Processed)
- FreeArgs(Args);
- }
- else
- {
- LONG Error = IoErr();
-
- SetIoErr(Error);
-
- Packet . Results[0] = RC_ERROR;
- Packet . Results[1] = IoErr();
- }
-
- /* Free parser data. */
-
- if(!Processed)
- FreeDosObject(DOS_RDARGS,Args);
- }
- else
- {
- Packet . Results[0] = RC_ERROR;
- Packet . Results[1] = ERROR_NO_FREE_STORE;
- }
-
- /* Free temporary buffer. */
-
- if(!Processed)
- FreeVecPooled(Array);
- }
- else
- {
- Packet . Results[0] = RC_ERROR;
- Packet . Results[1] = ERROR_NO_FREE_STORE;
- }
- }
- else
- {
- Packet . Array = NULL;
- Packet . Args = NULL;
-
- Processed = InvokeRexxCommand(&Packet);
- }
-
- if(!Processed)
- {
- if(Packet . Results[0] && Packet . Results[1])
- LastRexxError = Packet . Results[1];
-
- ReplyRexxCommand(RexxMsg,Packet . Results[0],Packet . Results[1]);
- }
-
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* RexxPktCleanup(struct RexxPkt *Packet,STRPTR Result):
- *
- * Free the memory allocated for a message packet.
- */
-
- VOID
- RexxPktCleanup(struct RexxPkt *Packet,STRPTR Result)
- {
- if(Packet -> Args)
- {
- FreeArgs(Packet -> Args);
-
- FreeDosObject(DOS_RDARGS,Packet -> Args);
- }
-
- FreeVecPooled(Packet -> Array);
-
- if(Packet -> Results[0])
- {
- /* Store error code. */
-
- if(Packet -> Results[1])
- {
- UBYTE Buffer[10];
-
- SPrintf(Buffer,"%ld",LastRexxError = Packet -> Results[1]);
-
- if(Packet -> RexxMsg)
- SetRexxVar(Packet -> RexxMsg,"TERM.LASTERROR",Buffer,strlen(Buffer));
- }
-
- ReplyRexxCommand(Packet -> RexxMsg,Packet -> Results[0],Packet -> Results[1]);
-
- if(Result)
- DeleteArgstring(Result);
- }
- else
- {
- if(Result)
- {
- if(Packet -> RexxMsg)
- {
- if(Packet -> RexxMsg -> rm_Action & RXFF_RESULT)
- ReplyRexxCommand(Packet -> RexxMsg,0,(LONG)Result);
- else
- {
- DeleteArgstring(Result);
-
- ReplyRexxCommand(Packet -> RexxMsg,0,0);
- }
- }
- else
- DeleteArgstring(Result);
- }
- else
- ReplyRexxCommand(Packet -> RexxMsg,0,0);
- }
- }
-
- /* RexxServer(VOID):
- *
- * Asynchronous ARexx host server.
- */
-
- VOID __saveds
- RexxServer(VOID)
- {
- /* Create the public host port. */
-
- if(RexxPort = CreateMsgPort())
- {
- struct RexxMsg *RexxMsg;
- ULONG SignalSet;
- BOOL Done = FALSE;
-
- InitSemaphore(&RexxLaunchSemaphore);
-
- RexxPort -> mp_Node . ln_Name = RexxPortName;
- RexxPort -> mp_Node . ln_Pri = 1;
-
- /* Make it a public port. */
-
- AddPort(RexxPort);
-
- /* Signal our father that we're running. */
-
- Signal(ThisProcess,SIG_HANDSHAKE);
-
- /* Go into loop and wait for input. */
-
- do
- {
- SignalSet = Wait(SIG_KILL | PORTMASK(RexxPort));
-
- /* Are we to quit? */
-
- if(SignalSet & SIG_KILL)
- Done = TRUE;
-
- /* This is probably a Rexx command. */
-
- if(SignalSet & PORTMASK(RexxPort))
- {
- /* Pick up all the messages. */
-
- while(RexxMsg = (struct RexxMsg *)GetMsg(RexxPort))
- {
- /* This is probably the reply to some
- * synchronous function invocation.
- */
-
- if(RexxMsg -> rm_Node . mn_Node . ln_Type == NT_REPLYMSG)
- FreeVecPooled(RexxMsg);
- else
- {
- /* At first try to run the
- * command asynchronously.
- * If this turns out to be
- * somewhat `impossible' pass
- * it to the `term' main process
- * or - if in batch mode - try
- * to deal with the message
- * on our own.
- */
-
- if(!ParseRexxCommand(RexxMsg))
- {
- UBYTE Buffer[10];
-
- SPrintf(Buffer,"%ld",LastRexxError = TERMERROR_UNKNOWN_COMMAND);
-
- SetRexxVar(RexxMsg,"TERM.LASTERROR",Buffer,strlen(Buffer));
-
- ReplyRexxCommand(RexxMsg,RC_ERROR,TERMERROR_UNKNOWN_COMMAND);
- }
- }
- }
- }
- }
- while(!Done);
-
- Done = FALSE;
-
- /* Process remaining messages. */
-
- do
- {
- while(RexxMsg = (struct RexxMsg *)GetMsg(RexxPort))
- {
- if(RexxMsg -> rm_Node . mn_Node . ln_Type == NT_REPLYMSG)
- FreeVecPooled(RexxMsg);
- else
- ReplyRexxCommand(RexxMsg,-1,0);
- }
-
- ObtainSemaphore(&RexxLaunchSemaphore);
-
- if(!RexxLaunchCount)
- {
- Done = TRUE;
-
- ReleaseSemaphore(&RexxLaunchSemaphore);
- }
- else
- {
- ReleaseSemaphore(&RexxLaunchSemaphore);
-
- WaitPort(RexxPort);
- }
- }
- while(!Done);
-
- DeleteMsgPort(RexxPort);
-
- RexxPort = NULL;
- }
-
- Forbid();
-
- RexxProcess = NULL;
-
- Signal(ThisProcess,SIG_HANDSHAKE);
- }
-
- /* HandleRexx():
- *
- * Tiny & simple subroutine to read and examine all
- * messages coming in to be processed synchronously
- * by the `term' main process.
- */
-
- BOOL
- HandleRexx()
- {
- struct RexxPkt *Packet;
-
- /* Obtain the message packet. */
-
- if(Packet = (struct RexxPkt *)GetMsg(TermRexxPort))
- {
- STRPTR Result;
-
- InRexx = TRUE;
-
- UpdateRequired = TransferUpdateRequired = FALSE;
-
- /* Execute the command. */
-
- Result = (*Packet -> CommandInfo -> Routine)(Packet);
-
- /* Free the packet data. */
-
- RexxPktCleanup(Packet,Result);
-
- /* Update the configuration if necessary. */
-
- if(UpdateRequired)
- ConfigSetup();
-
- /* Update the XPR options if necessary. */
-
- if(TransferUpdateRequired)
- {
- if(ProtocolSetup(TRUE))
- SaveProtocolOpts();
- }
-
- /* Return the message packet. */
-
- ReplyMsg((struct Message *)Packet);
-
- InRexx = FALSE;
-
- return(TRUE);
- }
- else
- return(FALSE);
- }
-